/*
作为内置类型的Class，使JS的优雅OOP成为可能
因为1519版本有bug，所以以1543版代码为例
*/
var Class = new Native({

 //族名,为$type提供精准类型判断
 name: 'Class',

 //JS way的构造函数，始于Prototype?
 initialize: function(properties){

  properties = properties || {};

  //真正用于返回的类的原型
  var klass = function(empty){

   //复制前先解除关联      
   for (var key in this) this[key] = $unlink(this[key]);
   
   //复制Class.Mutators的方法，使新类支持实现和继承
   for (var mutator in Class.Mutators){
    if (!this[mutator]) continue;
    Class.Mutators[mutator](this, this[mutator]);

    //已使用，移除
    delete this[mutator];
   }

   this.constructor = klass;
   
   //给构造函数传空函数时直接返回，不作后续处理
   if (empty === $empty) return this;
   
   //对于类本身的构造函数，将参数原样传递
   var self = (this.initialize) ? this.initialize.apply(this, arguments) : this;

   //对于参数中的方法，直接执行，不传递参数
   if (this.options && this.options.initialize) this.options.initialize.call(this);

   return self;
  };

  //将Class的特性复制给klass，相当于让klass继承Class
  $extend(klass, this);
  klass.constructor = Class;

  //指定原型
  klass.prototype = properties;
  return klass;
 }

});

//使用继承自Native的implement方法，让新的implement覆盖之
Class.implement({

 implement: function(){
  Class.Mutators.Implements(this.prototype, Array.slice(arguments));
  return this;
 }

});

Class.Mutators = {};

/*
使类支持Implements的写法实现
var myClass = new Class({
 Implements : [Events, Options],
 ...
});
*/
Class.Mutators.Implements = function(self, klasses){
 //$splat使支持多个Implements
 $splat(klasses).each(function(klass){
  $extend(self, ($type(klass) == 'class') ? new klass($empty) : klass);
 });
};

/*
使类支持Extends的写法继承
var myClass = new Class({
 Extends : Base,
 ...
});
*/
Class.Mutators.Extends = function(self, klass){
 klass = new klass($empty);
 for (var property in klass){
  var kp = klass[property];
  var sp = self[property];
  self[property] = (function(previous, current){
   //继承出现相同属性、方法时的处理
   if ($defined(current) && previous != current){
    var type = $type(current);
    if (type != $type(previous)) return current;
    switch (type){
     case 'function':
      return function(){
       //继承出现同名方法时，this.parent可以引用到父类的同名方法
       current.parent = this.parent = previous.bind(this);
       var value = current.apply(this, arguments);
       this.parent = current.parent;
       return value;
      };
     case 'object': return $merge(previous, current);
     default: return current;
    }
   }
   return previous;
  })(kp, sp);
 }
};